home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / game / pr / src / prgame.c < prev    next >
Text File  |  1995-08-18  |  11KB  |  437 lines

  1. /*===============================
  2.     "prgame.c" : racing game
  3. ===============================*/
  4. #include <fmcfrb.h>
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <math.h>
  8. #include "timekh.h"
  9. #include "pad.h"
  10. #include "prdef.h"
  11.  
  12. #define    startTM()    TIM_rdcalendar(&st)
  13. #define waitTM(_t)    do{TIM_rdcalendar( &et );}while(getTime(st,et)<(_t))
  14. #define readPad()    do{_outb(PADOUT,COM0);}while((_inb(PAD1IN)&COMIN)!=0);\
  15.                     pad=_inb(PAD1IN);
  16.  
  17. void putmap( int x0, int y0, int z0, vect ex, vect ey, vect ez );
  18. void putcar( int x0, int y0, int z0, vect ex, vect ey, vect ez, int cpol );
  19. int  mycar( short x, short y, short z, int ang, vect kv );
  20. int  encar( short x, short y, short z, int ang, vect kv, int col, int pol );
  21. void writeScreen();
  22. void clearVram(int a, int b, int c);
  23. int  onRoad( int x, int y, int n );
  24.  
  25. void putMess( char *str, int col );
  26. void putLapTime( int lap, int time, int best );
  27. void putRestTime( int rt );
  28. void clearMess();
  29. void putSpd( int spd );
  30. void putlmap();
  31. void setLap( short blp, short flp );
  32. #define putExTime() putMess("Extended Time",14)
  33.  
  34. static TIM_CALEN    st,et;
  35.  
  36. #define    CPMAX    10
  37. #define    PI        3.14159265
  38. #define    MaxSpd    8000
  39. #define    ACL        250
  40. #define    BRK        300
  41. //#define    GRP        40
  42. #define    Ekt     998
  43. #define    ANG(_a)    _a = (_a+20000)%10000
  44.  
  45. extern poly   car[3];
  46. extern rdata  *road;
  47.  
  48. #define slipFlag(col)    car[0].type=car[1].type= \
  49.                         (col)==0?C32K(31,0,0):C32K(0,31,0)
  50. #define    onRdFlag(col)    car[2].type=((col)>=0?C32K(31,0,15):C32K(20,20,0))
  51.  
  52. extern int _time[20],_dn;
  53. extern int *_cos,*_sin;
  54. extern short rd;
  55. extern short cpn, *cp;
  56. extern short *exTime;
  57.  
  58. extern way *way1st,*waybst;
  59. way *ecs[6]; //={waybst,waybst+1,waybst+2,way1st,way1st+1,way1st+2};
  60. way cway,pw1st,pwbst;
  61.  
  62. extern int   maxtime,h;
  63. extern int   lapFlag,wayFlag;
  64.  
  65. int pflap=0;
  66.  
  67. /*======================
  68.     ベクトル加工関数
  69. ======================*/
  70. vect ortholize( vect vec )
  71. {
  72.     int l ;
  73.     l = sqrt(vec.x*vec.x+vec.y*vec.y+vec.z*vec.z)*10 ;
  74.     if(l==0){
  75.         vec.z = 1000 ;
  76.         return vec;
  77.     }
  78.     vec.x = (int)vec.x*10000/l ;
  79.     vec.y = (int)vec.y*10000/l ;
  80.     vec.z = (int)vec.z*10000/l ;
  81.     return vec ;
  82. }
  83. vect exProduct( vect v1, vect v2 )
  84. {
  85.     vect kv;
  86.     int x1=v1.x,y1=v1.y,z1=v1.z ;
  87.     int x2=v2.x,y2=v2.y,z2=v2.z ;
  88.  
  89.     kv.x = (y1*z2 - z1*y2)/1000 ;
  90.     kv.y = (z1*x2 - x1*z2)/1000 ;
  91.     kv.z = (x1*y2 - y1*x2)/1000 ;
  92.     return kv ;
  93. }
  94. /*=========================
  95.     game 3D test version
  96. =========================*/
  97. void    game( short sx,short sy,short sang )
  98. {
  99.     int  pol, i,j;
  100.     int  x,y, spd=0,acl;
  101.     int  ang,mang;
  102.     int  ecx,ecy,ectime[6] = {-1,-1,-1,-1,-1,-1};
  103.     int  sfc, grip, onRd=0, ekt;
  104.     int  lapTime=30000, lap=0,messTime;
  105.     int  restTime=6000;
  106.     char lapflag[CPMAX]=0;
  107.     char pad;
  108.     int  mess=0,viewpt=1,viewtime=0;
  109.  
  110.     h = 150;    // [cm]
  111.     int  height=road[0].pz,xx,yy;
  112.     vect kv=road[0].k;
  113.     vect zv;    zv.x=0,zv.y=0,zv.z=1000;
  114.     int  brkf=0,bf,bs;
  115.  
  116.     vect    ex,ey,ez ;
  117.     int        vx,vy,vz, cs,sn ;
  118.  
  119.     for(i=0; i<cpn; ++i) lapflag[i]=1 ;
  120.     for(i=0; i<6; ++i )    ecs[i] = way1st+i ;
  121.     pw1st.ltime=0 ;
  122.     pwbst.ltime=0 ;
  123.  
  124.     x=sx*100, y=sy*100;
  125.     ang=mang=sang*10;
  126.     grip = (maxtime*MaxSpd*5/PI/1500)*MaxSpd; //*5000/Pi/150000/10
  127.     ekt=100000;
  128.     for(i=0; i<maxtime; ++i)
  129.         ekt = ekt*Ekt/1000;
  130.     ekt/=100;
  131.     putlmap();
  132.     putRestTime(-1) ;
  133.  
  134.     while(1)
  135.     {
  136.         startTM();
  137.         readPad();
  138.  
  139.     //    エスケープ
  140.         if(PUSH(PADRUN+PADSEL)) {
  141.             j=0; break;
  142.         }
  143.     //    視点変更
  144.         else if(PUSH(PADSEL)&&viewtime<=0)
  145.         {
  146.             viewpt++; viewpt%=3;
  147.             viewtime=50 ;
  148.         }
  149.         if( viewtime>0 ) viewtime-=maxtime;
  150.  
  151.     //    スタート時のハンドル固定
  152.         if( lap==0 ) pad = ~(PADA);
  153.  
  154.     //    ハンドルの操作
  155.         if(PUSH(PADU))        i = 120000;
  156.         else if(PUSH(PADD)) i = 30000;
  157.         else                i = 60000;
  158.         if(PUSH(PADL)) ang -= maxtime*spd*5000/PI/i/10;
  159.         if(PUSH(PADR)) ang += maxtime*spd*5000/PI/i/10;
  160.         ANG(ang);
  161.  
  162.     //    加速
  163.         acl=0;
  164.         brkf=0;
  165.         if (PUSH(PADA)&&PUSH(PADB)) acl = ACL*2/3;
  166.         else {
  167.             if (PUSH(PADA))    acl = ACL;
  168.             if (PUSH(PADB))    acl =-BRK,brkf=1;
  169.         }
  170.  
  171.     //    コース位置確認
  172.         onRd=onRoad( x,y,onRd );
  173.         if( onRd<0 )            //    コース外
  174.             acl -= BRK*2/3;
  175.         onRdFlag(onRd);
  176.  
  177.     //    高度算出
  178.         if( onRd>=0 ){
  179.             xx = x-road[onRd].px[0]*100 ;
  180.             yy = y-road[onRd].py[0]*100 ;
  181.             kv = road[onRd].k ;
  182.             //if ( 0!=kv.z) {
  183.                 height = road[onRd].pz-(kv.x*xx+kv.y*yy)/kv.z/10 ;
  184.             //}
  185.             //else {
  186.             //    height = road[onRd].pz ;
  187.             //    printf("onRd=[%d],(kz==0)\n",onRd);
  188.             //}
  189.         }else {
  190.             kv.x = kv.y = 0 ;
  191.             kv.z = 1000 ;
  192.         }
  193.  
  194.         ANG(mang);
  195.         bf = kv.x*_cos[mang/10]+kv.y*_sin[mang/10] ;
  196.         bs =-kv.x*_sin[mang/10]+kv.y*_cos[mang/10] ;
  197.     //    スリップの計算
  198.         i = (ang-mang+25000)%10000-5000;    //進行方向とのずれ角
  199.         //bs = bs ;    // bs=bs/1000/100*g*10000 ;
  200.         sfc = spd*i - bs ; // sin(i)*v *10000-bs
  201.         //    printf("bs=%d,sfc=%d,(bs&sfc)=%d\n",
  202.         //            bs,spd*i,sfc);
  203.         if (_abs(sfc)<=grip||spd==0) {
  204.             mang = ang;
  205.             j = 0;
  206.         } else {
  207.             if (sfc>0)
  208.                 mang += (grip-bs)/spd;
  209.             else
  210.                 mang -= (grip+bs)/spd; 
  211.             j = 1;
  212.         }
  213.         slipFlag(j);
  214.  
  215. //        i = (ang-mang+20000)%10000;
  216. //        mang += acl*_sin[i/10]*100/spd/PI;
  217. //        acl = acl*_cos[i/10]/100;
  218.         ANG(mang);
  219.  
  220.         acl += bf/600 ; // 600->適当 (^^;
  221.         spd = (    spd*ekt + MaxSpd*(1000-ekt)*acl/ACL )/1000;
  222.         if (spd<0) spd=0 ;
  223.  
  224.     //    位置の更新
  225.         x += spd*maxtime*_cos[mang/10]/1000;
  226.         y += spd*maxtime*_sin[mang/10]/1000;
  227.  
  228.     //    ExtendTime 表示と Lap 処理
  229.         if( onRd>=0 )
  230.         {
  231.           for(i=0; i<cpn; ++i)
  232.           {
  233.             if( onRd==cp[i] && lapflag[i]==0 )
  234.             {
  235.                 lapflag[i] = 1;
  236.                 restTime += exTime[i]*100;
  237.                 if( mess!=0 ) clearMess();
  238.                 putExTime();
  239.                 mess = 2;
  240.                 messTime = 500;
  241.                 cway.stime[i] = lapTime ;
  242.                 break;
  243.             }
  244.           }
  245.         }
  246.     //    メッセージの消去
  247.         if( mess!=0 ){
  248.             messTime -= maxtime;
  249.             if( messTime<0 )
  250.             {
  251.                 clearMess();
  252.                 mess=0;
  253.             }
  254.         }
  255.     //    LapTime の表示等 ラップ更新時の処理
  256.         if( onRd==0 )
  257.         {
  258.             for(i=0,j=1; i<cpn; ++i) j *= lapflag[i] ;
  259.             if( j==1 ){
  260.                 if( lap==0 ) restTime=6000;
  261.                 else cway.ltime = lapTime;
  262.                 if( lap==1 )
  263.                 {
  264.                     memcpy( &pw1st, &cway, sizeof(way) );
  265.                     for(i=0; i<6; ++i )    ecs[i] = waybst+i;
  266.                 }
  267.                 if( lap!=0 )
  268.                 {
  269.                     for(i=0; i<6; i++) ectime[i]=maxtime*3*(6-i);
  270.                     if (pwbst.ltime>=lapTime||pwbst.ltime==0) {
  271.                         memcpy( &pwbst, &cway, sizeof(way) );
  272.                     }
  273.                 }
  274.                 putLapTime(lap,lapTime,pwbst.ltime);
  275.                 mess=1,    messTime=600 ;
  276.                 lap++,    lapTime=0 ;
  277.                 memset( lapflag, 0, cpn );
  278.             }
  279.         }
  280.  
  281.     //    走行データの記録
  282.         if( lap!=0 && lapTime<10000 )
  283.         {
  284.             cway.pt[lapTime].x=x/100;
  285.             cway.pt[lapTime].y=y/100;
  286.             cway.pt[lapTime].z=height;
  287.             cway.ang[lapTime]=ang/10;
  288.         }
  289.         lapTime += maxtime;
  290.  
  291.     //    RestTime の処理
  292.         restTime -= maxtime;
  293.         if( lap>0 && restTime<0 ){
  294.             j = 1;
  295.             break;
  296.         }
  297.  
  298.     //    車ポリゴンのセット
  299.         pol=mycar( x/100,y/100,height,ang/10,kv );
  300.         for(j=0;j<6;j++)
  301.         {
  302.           if( ecs[j]->ltime!=0 ){
  303.             if( ectime[j]<0 ){
  304.                 ecx = x/100 + _cos[sang]*(6-j)/2;    // 5m*(6-j)
  305.                 ecy = y/100 + _sin[sang]*(6-j)/2;
  306.                 i = C32K((j+2)%2,((j+2)/2)%2,((j+2)/4)%2);
  307.                 pol = encar( ecx, ecy, height, sang, kv, i, pol );
  308.                 i = onRoad( ecx*100,ecy*100,rd-10 );
  309.                 if( i>=0 && i<10 ) ectime[j]=0;
  310.             }else {
  311.                 if( ectime[j]<=ecs[j]->ltime ){
  312.                     i = C32K((j+2)%2,((j+2)/2)%2,((j+2)/4)%2);
  313.                     pol=encar( ecs[j]->pt[ectime[j]].x,
  314.                                ecs[j]->pt[ectime[j]].y,
  315.                                ecs[j]->pt[ectime[j]].z,
  316.                                ecs[j]->ang[ectime[j]],
  317.                                zv/*ecs[j]->kv[ectime[j]]*/, i, pol
  318.                              );
  319.                     ectime[j]+=maxtime;
  320.                 }
  321.             }
  322.           }
  323.         }
  324.     //    画面表示
  325.         cs = cos(_PI*2*mang/10000)*1000;
  326.         sn = sin(_PI*2*mang/10000)*1000;
  327.         switch(viewpt){
  328.           case 1:
  329.             ey.x = kv.z*cs /1000 ;
  330.             ey.y = kv.z*sn /1000 ;
  331.             ey.z = -(kv.x*cs + kv.y*sn) /1000 ;
  332.             ey = ortholize( ey ) ;
  333.             ez.x = (1000-sn)*kv.x /1000 ;
  334.             ez.y = (1000-cs)*kv.y /1000 ;
  335.             ez.z = kv.z ;
  336.             ez = ortholize( ez ) ;
  337.             ex = exProduct( ez,ey ) ; // 左手系
  338.             vx = x/10-ey.x*h/400+ez.x*h/1000 ; // x,y[mm]
  339.             vy = y/10-ey.y*h/400+ez.y*h/1000 ; // h,height[cm]
  340.             vz = height-ey.z*h/400+ez.z*h/1000 ; // vx-z[cm]
  341.             break ;
  342.           case 2:
  343.             ey.x = kv.z*cs /1000 ;
  344.             ey.y = kv.z*sn /1000 ;
  345.             ey.z = -(kv.x*cs + kv.y*sn) /1000 ;
  346.             ey = ortholize( ey ) ;
  347.             ez.x = (1000-sn)*kv.x /1000 ;
  348.             ez.y = (1000-cs)*kv.y /1000 ;
  349.             ez.z = kv.z ;
  350.             ez = ortholize( ez ) ;
  351.             ex = exProduct( ez,ey ) ; // 左手系
  352.             vx = x/10-ey.x*h/180+ez.x*h/500 ; // x,y[mm]
  353.             vy = y/10-ey.y*h/180+ez.y*h/500 ; // h,height[cm]
  354.             vz = height-ey.z*h/180+ez.z*h/500 ; // vx-z[cm]
  355.             break ;
  356.           default :
  357.             ey.x = cs*5000/5099 ;
  358.             ey.y = sn*5000/5099 ;
  359.             ey.z = -1000*1000/5099 ;
  360.             ez.x = cs*1000/5099 ;
  361.             ez.y = sn*1000/5099 ;
  362.             ez.z = 1000*5000/5099 ;
  363.             ex = exProduct( ez,ey ) ; // 左手系
  364.             vx = x/10-ey.x*h/33+ez.x*h/100 ; // x,y[mm]
  365.             vy = y/10-ey.y*h/33+ez.y*h/100 ; // h,height[cm]
  366.             vz = height-ey.z*h/33+ez.z*h/100 ; // vx-z[cm]
  367.             break ;
  368.         }
  369. #if debug>=2
  370.     if(brkf){
  371.         printf("ex[%d,%d,%d]ey[%d,%d,%d]ez[%d,%d,%d],kv[%d,%d,%d]\n",
  372.             ex.x,ex.y,ex.z,
  373.             ey.x,ey.y,ey.z,
  374.             ez.x,ez.y,ez.z,
  375.             kv.x,kv.y,kv.z );
  376.     }
  377. #endif
  378.         clearVram( ex.z,ey.z,ez.z ) ;
  379.         putmap( vx,vy,vz, ex,ey,ez ) ;
  380.         putcar( vx,vy,vz, ex,ey,ez, pol ) ;
  381.         putSpd( spd*280/MaxSpd ) ;
  382.         if(lap>0) putRestTime(restTime/100) ;
  383.         writeScreen() ;
  384.  
  385.     //    カウント終了処理
  386.         TIM_rdcalendar( &et ) ;
  387.         i=getTime(st,et) ;
  388.         if (i<20) ++_time[i] ;
  389.         ++_dn ;
  390. //        if (_dn>=300) break ;
  391.  
  392.         waitTM(maxtime) ;
  393.     }
  394.     if( mess!=0 ){
  395.         clearMess();
  396.         mess=0;
  397.     }
  398.  
  399.     //    if( j==1 );    //    TimeOver
  400.     //    if( j==0 );    //    Retire
  401.  
  402.     i = (pwbst.ltime==0 ? 30000:pwbst.ltime) ;
  403.     j = (pw1st.ltime==0 ? 30000:pw1st.ltime) ;
  404.     setLap( (short)i, (short)j );
  405.     pflap = pw1st.ltime; // ?
  406.  
  407.     //    データの補間
  408.     extern makeUpWay( way *wd, int st, int ed );
  409.     for(i=0; i<pw1st.ltime; i+=maxtime)
  410.         makeUpWay( &pw1st,i,i+maxtime );
  411.     for(i=0; i<pwbst.ltime; i+=maxtime)
  412.         makeUpWay( &pwbst,i,i+maxtime );
  413.  
  414.     //    way データの更新
  415.     if (pw1st.ltime!=0&&(pw1st.ltime<=way1st[5].ltime||way1st[5].ltime==0))
  416.     {
  417.         for(i=0; i<6; ++i){
  418.             if (pw1st.ltime<=way1st[i].ltime||way1st[i].ltime==0)
  419.                 break ;
  420.         }
  421.         _rmemcpy( &way1st[i+1], &way1st[i], sizeof(way)*(5-i) );
  422.         _rmemcpy( &way1st[i], &pw1st, sizeof(way) );
  423.         wayFlag = 1;
  424.     }
  425.     if (pwbst.ltime!=0&&(pwbst.ltime<=waybst[5].ltime||waybst[5].ltime==0))
  426.     {
  427.         for(i=0; i<6; ++i){
  428.             if (pwbst.ltime<=waybst[i].ltime||waybst[i].ltime==0)
  429.                 break ;
  430.         }
  431.         _rmemcpy( &waybst[i+1], &waybst[i], sizeof(way)*(5-i) );
  432.         _rmemcpy( &waybst[i], &pwbst, sizeof(way) );
  433.         wayFlag = 1;
  434.     }
  435. }
  436.  
  437.